/*
 * input_file.cpp
 *
 *  Created on: May 12, 2010
 *      Author: snirgaz
 */

#include "InputFile.h"
#include <iostream>
using namespace std;
template<>
ToMeasure readXmlData(pugi::xml_node node, string xmlName) {
	pugi::xml_node foundNode;
	ToMeasure measure;
	try {
		foundNode = node.child(xmlName.c_str());
		if (foundNode.empty())
			throw(string("Missing Data!" + xmlName));
		for (pugi::xml_node_iterator it = foundNode.begin();
				it != foundNode.end(); ++it) {
			measure.insert(
					pair<string, bool>(boost::lexical_cast<string>(it->name()),
							boost::lexical_cast<bool>(it->child_value())));
		}
	} catch (string &error) {
		std::cout << error;
		exit(1);
	}
	return measure;
}
template<>
IndexType readXmlData(pugi::xml_node node, string xmlName) {
	pugi::xml_node foundNode;
	IndexType indexValues;
	try {
		foundNode = node.child(xmlName.c_str());
		if (foundNode.empty())
			throw(string("Missing Data!" + xmlName));
		int d = 0;
		for (pugi::xml_node_iterator it = foundNode.begin();
				it != foundNode.end(); ++it) {
			indexValues[d++] = boost::lexical_cast<IndexType::value_type>(
					it->child_value());
		}
	} catch (string &error) {
		std::cout << error;
		exit(1);
	}
	return indexValues;
}
InputFile::InputFile(string fileName) :
		fileName_(fileName) {
}
void InputFile::readFile() {
	pugi::xml_document xmlDoc;
	pugi::xml_node rootNode, simParam;
	try {
		pugi::xml_parse_result result = xmlDoc.load_file(fileName_.c_str());
		if (!result)
			throw result;
	} catch (pugi::xml_parse_result &result) {
		std::cout << "Error description: " << result.description() << "\n";
		exit(1);
	}
	try {
		rootNode = xmlDoc.child("SIMULATION");
		if (rootNode.empty())
			throw string("Bad File Type");
	} catch (string & Error) {
		std::cout << Error;
		exit(1);
	}
	// Lattice Data
	qmcParameters_.Llist.setVal(readXmlData<IndexType>(rootNode, "L_LIST"));
	qmcParameters_.numOfBins.setVal(readXmlData<int>(rootNode, "NUM_OF_BINS"));
	qmcParameters_.binSize.setVal(readXmlData<int>(rootNode, "BIN_SIZE"));
	// BS Bins
	int totalSample = (int) pow((double) qmcParameters_.binSize.getVal(),
			qmcParameters_.numOfBins.getVal());
	int binSize = qmcParameters_.binSize.getVal()
			* qmcParameters_.binSize.getVal();
	int numOfBins = totalSample / binSize;
	qmcParameters_.numOfBinsBS.setVal(numOfBins);
	qmcParameters_.binSizeBS.setVal(binSize);
	qmcParameters_.outPath.setVal(readXmlData<string>(rootNode, "OUTPATH"));
	qmcParameters_.g.setVal(readXmlDataOrDefault<double>(rootNode, "G", 1.));
	qmcParameters_.endTime.setVal(readXmlData<double>(rootNode, "END_TIME"));
	qmcParameters_.initFromFile.setVal(
			readXmlData<bool>(rootNode, "INIT_FROM_FILE"));
	qmcParameters_.toMeasure.setVal(
			readXmlData<ToMeasure>(rootNode, "MEASUREMENTS"));
	qmcParameters_.runNum.setVal(readXmlData<string>(rootNode, "RUN_NUM"));
	qmcParameters_.deltaDump.setVal(
			readXmlData<double>(rootNode, "DELTA_DUMP"));
	qmcParameters_.beta.setVal(readXmlData<double>(rootNode, "BETA"));
	qmcParameters_.seed.setVal(readXmlData<double>(rootNode, "SEED"));
	qmcParameters_.cutOff.setVal(readXmlData<int>(rootNode, "CUT_OFF"));
	qmcParameters_.numCutOffAdjust.setVal(
			readXmlData<int>(rootNode, "NUM_CUT_OFF"));
	qmcParameters_.rate.setVal(readXmlDataOrDefault<int>(rootNode, "RATE", 1));
	qmcParameters_.numOfOmegaMat.setVal(
			readXmlData<int>(rootNode, "NUM_OMEGA_MAT"));

}

QmcParameters& InputFile::getQmcParams() {
	return qmcParameters_;
}
